-module(product_handler).
-author("").

-export([init/3, allowed_methods/2, content_types_accepted/2, content_types_provided/2,
         delete_resource/2, delete_completed/2]).

-export([get_product/2, put_product/2]).

init(_Transport, _Req, []) ->
  {upgrade, protocol, cowboy_rest}.

allowed_methods(Req, State) ->
  {[<<"GET">>, <<"POST">>, <<"DELETE">>], Req, State}.

content_types_accepted(Req, State) ->
  {[{{<<"application">>, <<"json">>, []}, put_product}],
   Req, State}.

content_types_provided(Req, State) ->
  {[{{<<"application">>, <<"json">>, []}, get_product}],
   Req, State}.

get_product(Req, State) ->
  case cowboy_req:binding(product_id, Req) of
    {undefined, Req1} ->
      {ok, Req2} = cowboy_req:reply(400, [], "Invalid product id", Req1),
      {ok, Req2, State};
    {ProductId, Req1} ->
      get_product_response(Req1, State, ProductId)
  end.

put_product(Req, State) ->
  {ok, Body, Req1} = cowboy_req:body(Req),
  case jsx:is_json(Body) of
    true ->
      {ok, ProductId} = cn2p_catalog:add_product(jsx:decode(Body)),
      LocationHeader = {<<"Location">>, get_product_url(ProductId)},
      {ok, Req2} = cowboy_req:reply(201, [LocationHeader], [], Req1),
      {ok, Req2, State};
    false ->
      {ok, Req2} = cowboy_req:reply(415, Req1),
      {ok, Req2, State}
  end.

get_product_response(Req, State, ProductId) ->
  case cn2p_catalog:get_product(ProductId) of
    {ok, Product} -> {jsx:encode(Product), Req, State};
    {error, not_found} ->
      http_util:get_product_not_found_response(Req, State, ProductId)
  end.

delete_resource(Req, State) ->
  cn2p_catalog:delete_products_and_reviews(),
  {true, Req, State}.

delete_completed(Req, State) ->
  {ok, Req1} = cowboy_req:reply(200, Req),
  {true, Req1, State}.

get_product_url(ProductId) ->
  {ok, UrlBase} = application:get_env(cn2p_product_catalog_service, service_uri),
  <<(list_to_binary(UrlBase))/binary, "/api/product/", ProductId/binary>>.